1

我有一个超类DemoPage和几个子类SDemoPageEDemoPage等等。所有这些页面上都有完全相同的元素,看起来像上的 id 和看起来像SDemoPages-demo-test1的相应 id 。在我的类中,我已经声明了所有元素,并且我需要一种方法来添加基于子类(调用类)的 id。这就是我目前所拥有的。EDemoPagee-demo-test1DemoPage

class DemoPage
  include PageObject

  @@subclass_ids = {"SDemoPage" => "s-demo-",
   "EDemoPage" => "e-demo-"}

  # class << self; attr_accessor :current_class_id; end

  def initialize(browser, something)
    initialize_elements
    super(browser, something)
  end

  .........

  def initialize_elements
    self.instance_eval do
      select_list(:facility, id: "#{@current_class_id}facility")
      text_field(:account, id: "#{@current_class_id}account")
      text_field(:service, id: "#{@current_class_id}service")
   end
  end
end

class SDemoPage < DemoPage
  include PageObject

  @current_class_id = "s-demo-"
end

但这不起作用。我得到错误,undefined method 'select_list' for #<SDemoPage>...

这不是我最初的尝试。我首先尝试设置一个 attr_accessor :current_page_id,然后对其进行初始化,但这也没有用。然后我尝试打开元类并在那里设置 id。最后我做了我在这里设置一个类实例变量的地方SDemoPage,我终于能够让它与这段代码一起工作:

class DemoPage
  include PageObject

  def initialize(browser, something)
    super(browser, something)
  end

  .........

  SDemoPage.instance_eval do
    select_list(:facility, id: "#{@current_class_id}facility")
    text_field(:account, id: "#{@current_class_id}account")
    text_field(:service, id: "#{@current_class_id}service")
  end
end

但这不允许我根据其他调用类设置 id。

我还从其他一些尝试中留下了一些代码,例如使用哈希查找,但是在页面对象方法已经意识到变量/方法 @current_class_id 不存在之后,这些仍然在初始化方法中设置了实例变量

我不确定从这里去哪里。


编辑:

所以我终于想通了,但我不确定这是否是解决这个问题的最佳方法:

class DemoPage
  include PageObject
  include DataMagic

  def initialize(browser, visit)
    super(browser, visit)
    instantiate_elements self.class
  end

  def instantiate_elements klass
    klass.class_eval do
      select_list(:facility, id: "#{@class_id}facility")
      text_field(:account, id: "#{@class_id}account")
      text_field(:service, id: "#{@class_id}service")
    end
  end
end

class SDemoPage < DemoPage
  include PageObject
  @class_id = "s-demo-"
end

这样做有什么问题吗?我确实需要修补初始化方法,因为其中还有其他东西我没有在这里展示。因此,既然我已经需要这样做了,有没有理由不在SDemoPage实际的上下文中“创建”元素DemoPage?还是贾斯汀的回答完全是更好的做事方式?

编辑 2:我接受了贾斯汀的回答,因为在极少数情况下,我不需要修改 PageObject 中的初始化方法,他的回答会减少重复和整体代码。

4

1 回答 1

2

我认为最简单的解决方案是:

  1. 为调用访问器方法的 DemoPage 定义一个类方法
  2. 在子页面调用此方法,将id部分作为参数传递

DemoPage 将是:

class DemoPage
    include PageObject

    def self.common_demo_elements(class_id)
        select_list(:facility, id: "#{class_id}facility")
        text_field(:account, id: "#{class_id}account")
        text_field(:service, id: "#{class_id}service")      
    end
end

而子页面将是:

class SDemoPage < DemoPage    
    common_demo_elements("s-demo-")
end
于 2014-01-22T21:15:45.810 回答