1

我有一个包含 3 个 div 的地址(主地址、辅助地址、添加地址)的表单。每个 div 包含以下元素 (text_field):姓名、地址、电话。根据场景,我想编辑特定 div 的文本字段。

所以我有这种情况:

Given I am at the form for editing addresses
When the div "main address" is visible
Then fill the "name" element for the "main address" div
And erase the "address" for the "main address" div

以及以下步骤定义:

Then(/^fill the "([^"]+)" element for the "([^"]+)" div$/) do |element, div|
   on_page(AddressPage).fill_element element div
end

现在我不确定的部分 - 地址页面

class AddressPage
  include PageObject
  include DataMagic
  div(:main_address, :id => 'main_address')
  div(:secondary_address, :id => 'secondary_address')
  div(:add_address, :id => 'add_address')

  def fill_element(element, div)
    current_div = self.send("#{div}_element")
    # now the part I don't know how to do:
    current_element = div.search_within(current_div, element)
    fill_with_correct_data current_element
  end

  def search_within(div, element)
    # How to do this?
  end
end

我怎样才能做到这一点,这样我就不必为所有 div 定义所有元素(div 的数量是动态的)?我需要知道的是,是否有一种方法可以搜索一个元素以使其位于另一个元素中。

谢谢 :)


编辑html 将如下所示:

<div id='main_address'>
    <input id='name'>
    </input>
    <input id='address'>
    </input>
    <input id='phone'>
    </input>
</div>
<div id='secondary_address'>
    <input id='name'>
    </input>
    <input id='address'>
    </input>
    <input id='phone'>
    </input>
</div>
<div id='add_address'>
    <input id='name'>
    </input>
    <input id='address'>
    </input>
    <input id='phone'>
    </input>
</div>

第二次编辑重点是还要声明这一点:

select_list(:name, :id => 'name')
select_list(:address, :id => 'address')
select_list(:phone, :id => 'phone')

#Is this possible?
current_name_element = main_address.name
#?
#Also, at the end the point is to call the Datamagic populate_page_with method
populate_page_with data_for 'new_user'

“default.yml”看起来像这样:

new_user:
  name: ~first_name
  address: ~address
  phone: ~phone

我可以在哪里选择将填充哪个 div。这可能吗?

4

1 回答 1

1

您可以使用元素定位器在元素中查找元素。这些方法使用与访问器方法中相同类型的定位器。

例如,对于给定的current_div,您可以获得其相关的文本字段:

current_element = current_div.text_field_element(:id => 'name')
current_element = current_div.text_field_element(:id => 'address')
current_element = current_div.text_field_element(:id => 'phone')

注意:您可能需要更改这些定位器。大概这些 id 并不完全正确,因为 id 在页面上应该是唯一的。

将上述内容应用于您的页面对象,您可以将fill_element方法定义为:

def fill_element(element, div)
  current_div = self.send("#{div}_element")   
  current_element = current_div.text_field_element(:id => element)

  # I assume this is a method you have already
  fill_with_correct_data current_element
end

调用该方法就像:

page.fill_element('name', 'main_address')
page.fill_element('address', 'secondary_address')
page.fill_element('phone', 'add_address')

更新 - 创建范围定位器:

这似乎有点混乱,但考虑到页面对象 gem 的当前实现,这是我能想到的最好的。我认为有一些对 gem 的积压功能请求可以使这个更干净。

你可以做的是:

class AddressPage
    include PageObject

    class ScopedLocator
        def initialize(name, page_object)
            @name = name
            @page = page_object
        end

        def populate_with(data)
            scoped_data = Hash[data.map {|k, v| ["#{@name}_#{k}", v] }]
            @page.populate_page_with scoped_data
        end

        def method_missing(m, *args)  
            @page.send("#{@name}_#{m}", *args)
        end
    end

    ['main_address', 'secondary_address', 'add_address'].each do |name|
        define_method(name) { ScopedLocator.new(name, self) }
        text_field("#{name}_name"){ div_element(:id => name).text_field_element(:id => 'name') }
        text_field("#{name}_address"){ div_element(:id => name).text_field_element(:id => 'address') }
        text_field("#{name}_phone"){ div_element(:id => name).text_field_element(:id => 'phone') }
    end  
end

这做了两件事:

  1. 它将为每个地址创建正常的访问器。例如,它创建了一个 :main_address_name、:main_address_address 和 :main_address_phone (以及其他地址类型)。
  2. 它创建一个方法,例如main_address将操作委托给普通访问器。这是给出main_address.populate_with语法。

使用此页面对象,您可以对给定的地址部分执行 populate_with:

page.main_address.populate_with data_for 'new_user'
page.secondary_address.populate_with data_for 'new_user'
page.add_address.populate_with data_for 'new_user'

以及能够更新地址的各个字段。例如:

page.main_address.name = 'user'
于 2014-03-12T15:01:10.243 回答