如何添加动态一SitePrism页面对象的部分? [英] How to add a section to a SitePrism page object dynamically?

查看:213
本文介绍了如何添加动态一SitePrism页面对象的部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用SitePrism测试我的Web应用程序。我有一些扩展类 SitePrism ::页和一些常用的HTML片段的重新通过匹配扩展类psented $ P $ SitePrism ::科

I'm using SitePrism to test my web application. I have a number of classes that extend SitePrism::Page and a number of often-used HTML snippets are represented by matching classes extending 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,其中一个页面可以通过选择组装的模板的基础上pre定义的内容,然后拖动-and惊叹的任意数量的可用组件到页面上。

The problem is, the application I'm working on is based on a CMS, in which a page can be assembled by selecting a Template based on pre-defined content and then drag-and-dropping any number of available components onto the page.

最初的开发人员创建一个的页面对象的镜像每个可用的模板的。这是正常,只要试验次数低,无不是我们已经在我们的功能文件,以测试页面太多的变种。

The initial developers created a Page Object to mirror every available Template. This was fine as long as the number of tests was low and there weren't too many variants of pages that we had to test in our feature files.

由于增加了多个测试用例,页面对象开始以惊人的速度增长。

With the addition of multiple test cases, the page objects started growing at an alarming rate.

虽然我们可以很容易地通过定义减轻code复制的的在CMS提供跨重复使用它们每一个组件的页面对象的,但只是很多的属性很少习惯。

While we can easily mitigate code duplication by defining Sections for every component available in the CMS and reusing them across Page Objects, there's just a lot of properties that rarely get used.

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办法一节动态地添加到的页面对象的实例的,而不是整个班级?

Is there a way in SitePrism to dynamically add a section to an instance of a Page Object as opposed to a whole class?

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选择器泄漏到步骤定义,这通常是一个不好的做法。

It also worries me that doing something like this would potentially cause CSS selectors to leak into the step definitions, which is generally a bad practice.

要解决这个另一种方法是建立的页面对象的为相对于通用的模板页面的具体例子。在模板页面对象的可能只是包含任何的烤成模板,并可以扩展其他的 的那面镜子特定页面,采取的差异照顾页面对象。这听起来像一个更清洁的方式,所以我可能会写我的测试这样

Another way to work around this would be to build Page Objects for specific examples of pages as opposed to the versatile templates. The Template Page Objects could just contain whatever's baked into the templates and be extended by other Page Objects that mirror specific pages, taking care of the differences. It sounds like a much cleaner approach so I'm probably going to write my tests this way

总之,问题的技术部分代表。不管如何好或坏的想法是的,我怎么会用动态的附加部分扩展页面对象?我只是好奇。

Anyway, the technical part of the question stands. Regardless of how good or bad an idea it is, how could I dynamically extend a page object with an additional section? I'm just curious.

推荐答案

我在一个点想做的事你谈论的pretty同样的原因是什么。我们有可能有被拖入他们的新内容部分页面;使他们非常有活力。我尝试过的方式来做到这一点,从来没有发现任何我特别喜欢。

I had at one point wanted to do what you're talking about for pretty much the same reason. We had pages that could have new content-sections dragged into them; making them very dynamic. I experimented with ways to do this and never found any that I particularly liked.

现场棱镜元素部分方法各限定数量为类方法。你可以称之为 MyPage.section 在您的测试或添加调用 self.class.section 的方法并用它来加上新的栏目。但是,这些将存在该页面的所有实例;可能不是你想要的。

Methods like element and sections in site-prism each define a number of methods for the class. You could call MyPage.section in your test or add a method that calls self.class.section and use that to add on new sections. But those will exist for all instances of that page; probably not what you want.

您可以或者通过singleton_class上钉他们:

You could alternatively tack them on to through the singleton_class:

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

但是,这变得有点难看折腾到你的测试,对吧?

But that's getting a bit ugly to toss into your tests, right?

我一直以为节应该有一个default_locator(但很难获得补丁接受)结果
随着我们可以概括这一点:

I've long thought that Sections should have a default_locator (but tough to get patches accepted)
With that we could generalize this a bit:

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

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

And then you can use these as the parents.

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

在另一手它确实可能更容易刚刚创建页面对象的一些不同的变化在测试中使用。 (你真的要测试的许多变化?Maybe..maybe不是。)

On the other-hand it really might be easier to just create a few different variations of the page-object for use in tests. (Are you really going to test that many variations? Maybe..maybe not.)

这篇关于如何添加动态一SitePrism页面对象的部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆