针对类似页面部分的Ruby PageObject设计

针对类似页面部分的Ruby PageObject设计,ruby,angular,selenium,watir,page-object-gem,Ruby,Angular,Selenium,Watir,Page Object Gem,我使用的是Cheezy Page对象gem(这也意味着我使用的是Watir,这也意味着我使用的是Selenium)。我还显式加载了watir gem 无论如何,我有一个网站,我用angular编写的UI建模,其中有一个页面的内容根据下拉选择而改变。该页面有多个部分,但每个下拉选项都明显相同。唯一的区别是我使用的xpath定位器(在节上没有唯一的ID) 例如,我有一个类似于html/body/div[1]/div/div[1]/div/**green**/div/div[1] 还有一个 html/

我使用的是Cheezy Page对象gem(这也意味着我使用的是Watir,这也意味着我使用的是Selenium)。我还显式加载了watir gem

无论如何,我有一个网站,我用angular编写的UI建模,其中有一个页面的内容根据下拉选择而改变。该页面有多个部分,但每个下拉选项都明显相同。唯一的区别是我使用的xpath定位器(在节上没有唯一的ID)

例如,我有一个类似于
html/body/div[1]/div/div[1]/div/**green**/div/div[1]

还有一个

html/body/div[1]/div/div[1]/div/**red**/div/div[1]
html/body/div[1]/div/div[1]/div/red/div/div[1]/**<element>**
奇怪的是,节上的元素都具有相同的ID属性和相同的类名。因此,我一直在为元素使用xpath,因为这似乎使它成为一个唯一的定位器

问题是目前有七个下拉选项,每个选项都有几个类似的部分。它们具有明显相同的元素和结构(从最终用户的角度来看),但当您查看html时,唯一的区别是元素的定位器如下所示:

html/body/div[1]/div/div[1]/div/green/div/div[1]/**

还有一个

html/body/div[1]/div/div[1]/div/**red**/div/div[1]
html/body/div[1]/div/div[1]/div/red/div/div[1]/**<element>**
EDIT2:为每个请求添加页\节内容。所有期权卡至少共享这些要素。细节卡中的元素不同,但结构与选项卡相同

class OptionRedCard
  include PageObject

  def field1_limit
    text_field_element(xpath: "/html/body/app-component/app-page/div[2]/div/div/div[1]/div/div/div/ngb-tabset/div/div/red-unit/div[2]/div[2]/div/div/div/red/form/div/div/div/table/tbody/tr[2]/td[2]/div/div[1]/div/currency/div/input")
  end

  def field1_agg
    text_field_element(xpath: "/html/body/app-component/app-page/div[2]/div/div/div[1]/div/div/div/ngb-tabset/div/div/red-unit/div[2]/div[2]/div/div/div/red/form/div/div/div/table/tbody/tr[2]/td[2]/div/div[2]/div/currency/div/input")
  end

  def field2_limit
    text_field_element(xpath: "/html/body/app-component/app-page/div[2]/div/div/div[1]/div/div/div/ngb-tabset/div/div/red-unit/div[2]/div[2]/div/div/div/red/form/div/div/div/table/tbody/tr[3]/td[2]/div/div[1]/div/currency/div/input")
  end

  def field2_agg
    text_field_element(xpath: "/html/body/app-component/app-page/div[2]/div/div/div[1]/div/div/div/ngb-tabset/div/div/red-unit/div[2]/div[2]/div/div/div/red/form/div/div/div/table/tbody/tr[3]/td[2]/div/div[2]/div/currency/div/input")
  end

  def field3_limit
    text_field_element(xpath: "/html/body/app-component/app-page/div[2]/div/div/div[1]/div/div/div/ngb-tabset/div/div/red-unit/div[2]/div[2]/div/div/div/red/form/div/div/div/table/tbody/tr[4]/td[2]/div/div[1]/div/currency/div/input")
  end

  def field3_agg
    text_field_element(xpath: "/html/body/app-component/app-page/div[2]/div/div/div[1]/div/div/div/ngb-tabset/div/div/red-unit/div[2]/div[2]/div/div/div/red/form/div/div/div/table/tbody/tr[4]/td[2]/div/div[2]/div/currency/div/input")
  end

  def field1_agg_value
    field1_agg.attribute_value('data-value')
  end

  def field2_agg_value
    field2_agg.attribute_value('data-value')
  end

  def field3_agg_value
    field3_agg.attribute_value('data-value')
  end

end

我认为您的问题的简短答案是否定的,没有内置的对向页面部分传递值的支持。然而,这里有一些我可以想到的选择

选项1-使用初始化访问器

访问器通常在编译时执行。但是,您可以使用#initialize_accessors方法将执行延迟到页面对象(或节)的初始化。这将允许您在基类中定义访问器,该基类在初始化时将颜色类型插入路径:

class BaseCard
  include PageObject

  def initialize_accessors
    # Accessors defined with placeholder for the color type
    self.class.text_field(:field1_limit, xpath: "/html/body/some/path/#{color_type}/more/path/input")      
  end
end

# Each card class would define its color for substitution into the accessors
class OptionRedCard < BaseCard
  def color_type
    'red'
  end
end

class OptionGreenCard < BaseCard
  def color_type
    'green'
  end
end

class BasePO
  include PageObject

  page_section(:options_red_card, OptionRedCard, xpath: '/html/body/path')
  page_section(:options_green_card, OptionGreenCard, xpath: '/html/body/path')
end

@yudi2312您是否建议,即使在本文中没有针对这个特定的案例显示,在xpath页面部分和元素中使用正则表达式?我认为正则表达式在这方面不会有帮助。如果我错了,请纠正我,所有部分都有相同的元素,每个元素在所有部分中都有相同的属性,对吗?是的,有一些选项会生成包含额外元素的部分,但大多数都是完全相同的部分和具有相同属性的完全相同的元素。您是否尝试过使用
可见的
定位器?