加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 如何动态地向SitePrism页面对象添加节?

发布时间:2020-12-17 02:48:46 所属栏目:百科 来源:网络整理
导读:我正在使用SitePrism来测试我的Web应用程序.我有许多扩展SitePrism :: Page的类,许多经常使用的 HTML片段由扩展SitePrism :: Section的匹配类表示 class Login SitePrism::Section element :username,"#username" element :password,"#password" element :si
我正在使用SitePrism来测试我的Web应用程序.我有许多扩展SitePrism :: Page的类,许多经常使用的 HTML片段由扩展SitePrism :: Section的匹配类表示

class Login < SitePrism::Section
  element :username,"#username"
  element :password,"#password"
  element :sign_in,"button"
end

class Home < SitePrism::Page
  section :login,Login,"div.login"
end

问题是,我正在处理的应用程序基于CMS,其中可以通过基于预定义内容选择模板然后将任意数量的可用组件拖放到页面上来组装页面.

最初的开发人员创建了一个Page Object来镜像每个可用的Template.只要测试数量很少并且我们不得不在我们的功能文件中测试的页面变体太多,这就没问题了.

随着多个测试用例的增加,页面对象开始以惊人的速度增长.

虽然我们可以通过为CMS中可用的每个组件定义Sections并在页面对象中重用它们来轻松地减轻代码重复,但是很多属性很少被使用.

class BlogPost < SitePrism::Page

    section :logo,MySite::Components::Logo,'.logo'    
    section :navigation,MySite::Components::Navigation,'.primary-navigation'
    section :header,MySite::Components::BlogHeader,'.header'
    section :introduction,MySite::Components::Text,'.text .intro'
    # and so on,a lot of dynamic staff that could potentially be dropped onto the page
    # but does not neccessarily be there,going in dozens of lines
end

SitePrism中是否有一种方法可以动态地将一个节添加到Page对象的实例而不是整个类?

Then(/^Some step$/) do
    @blog = PageObjects::BlogPost.new()
    @blog.load("some url")
    @blog.somehow_add_a_section_here_dynamically
    expect (@blog.some_added_section).to be_visible
end

它还让我担心,做这样的事情可能会导致CSS选择器泄漏到步骤定义中,这通常是一种不好的做法.

解决此问题的另一种方法是为特定的页面示例构建页面对象,而不是通用模板.模板页面对象可以只包含模板中的任何内容,并由镜像特定页面的其他页面对象进行扩展,从而处理差异.这听起来像一个更清洁的方法,所以我可能会这样写我的测试

无论如何,问题的技术部分代表着.无论一个想法有多好或多坏,我怎样才能动态扩展一个带有附加部分的页面对象?我只是好奇.

解决方法

出于同样的原因,我曾经一度想做你正在谈论的事情.我们的页面可能会有新的内容部分被拖入其中;使他们非常有活力.我尝试了这样做的方法,从来没有发现任何我特别喜欢的东西.

像site-prism中的元素和部分这样的方法每个都为这个类定义了许多方法.您可以在测试中调用MyPage.section或添加一个调用self.class.section的方法,并使用它来添加新的部分.但那些页面的所有实例都会存在;可能不是你想要的.

你也可以通过singleton_class来解决它们:

my_page = MyPage.new
my_page.singleton_class.section(:new_section,NewSection,'#foo')

但是,进入你的测试会有点难看,对吗?

我一直以为Sections应该有一个default_locator(但很难接受补丁)
有了这个,我们可以概括一点:

class DynamicSection < SitePrism::Section
  def self.set_default_locator(locator)
    @default_locator = locator
  end
  def self.default_locator
    @default_locator
  end
end      

class DynamicPage < SitePrism::Page
  # add sections (and related methods) to this instance of the page
  def include_sections(*syms)
    syms.each do |sym|
      klass = sym.to_s.camelize.constantize
      self.singleton_class.section(sym,klass,klass.default_locator)
    end
  end
end

然后你可以用这些作为父母.

class FooSection < DynamicSection
  set_default_locator '#foo'
  element :username,"#username"
end

class BlogPostPage < DynamicPage
  # elements that exist on every BlogPost
end

在测试中:

@page = BlogPostPage.new
@page.include_sections(:foo_section,:bar_section)
expect(@page.foo_section).to be_visible

另一方面,为了在测试中使用,创建页面对象的一些不同变体可能更容易. (你真的要测试那么多变化吗?也许……不可能.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读